import { Post, Get, Patch, Base } from '@/axios'
import config from '@/config'
import router from '@/router'
import store from '@/store'
import types from '@/store/mutation-types'

const loginURL = 'https://gitee.com/oauth/token'
const notificationURL = 'https://gitee.com/api/v5/notifications/threads'
const setReadNoticeURL = 'https://gitee.com/api/v5/notifications/threads/:id'
const setReadUserMessageURL = 'https://gitee.com/api/v5/notifications/messages/:id'
const getUserMessageURL = 'https://gitee.com/api/v5/notifications/messages'
const refreshAccessTokenURL = 'https://gitee.com/oauth/token'

const getPath = (url, params) => {
  Object.keys(params).map(key => {
    url = url.replace(new RegExp(`:${key}`, 'g'), params[key])
  })
  return url
}

const httpFilter = async (request) => {
  return new Promise((resolve, reject) => {
    request
      .then((data) => {
        resolve(data)
      })
      .catch(async err => {
        const originalConfig = err.response.config
        if (err.response.status === 401) {
          let userInfo
          try {
            userInfo = await refreshAccessToken()
            store.commit(types.SET_USER_INFO, userInfo)
            resolve(await Base({
              data: originalConfig.data,
              headers: originalConfig.headers,
              method: originalConfig.method,
              params: { ...originalConfig.params, access_token: userInfo.access_token }
            }))
          } catch (err) {
            router.push({ name: 'login' })
          }
        }
        reject(err)
      })
  })
}

export const login = async (loginInfo) => {
  return Post(loginURL, {
    grant_type: 'password',
    client_id: config.clientID,
    client_secret: config.clientSecret,
    scope: 'user_info',
    ...loginInfo
  })
}

export const refreshAccessToken = async () => {
  return Post(refreshAccessTokenURL, undefined, {
    params: {
      grant_type: 'refresh_token',
      refresh_token: store.state.login.userInfo.refresh_token
    }
  })
}

export const fetchNotifications = async ({
  page = 1,
  type = 'referer',
  unread = false,
  participating = false
} = {}) => {
  return httpFilter(Get(notificationURL, {
    access_token: store.state.login.userInfo.access_token,
    unread,
    participating,
    type,
    page,
    per_page: config.listPerPage
  }))
}

/**
 * 设置消息已读
 * @param {String|Number} id 通知 ID
 */
export const setNoticeRead = async (id) => {
  const url = getPath(setReadNoticeURL, { id })
  return httpFilter(Patch(url, {
    access_token: store.state.login.userInfo.access_token
  }))
}

export const setUserMessageRead = async (id) => {
  const url = getPath(setReadUserMessageURL, { id })
  return httpFilter(Patch(url, {
    access_token: store.state.login.userInfo.access_token
  }))
}

/* eslint-disable camelcase */
export const getUserMessages = async ({
  unread = false,
  ids = [],
  page = 1,
  per_page = config.listPerPage
} = {}) => {
  return httpFilter(Get(getUserMessageURL, {
    access_token: store.state.login.userInfo.access_token,
    ids,
    unread,
    page,
    per_page
  }))
}
